package Interact;
// 使用缓冲区解决通信--管程法
// 生产者，消费者，产品及缓冲区
public class TestPC {
    public static void main(String[] args) {
        synContainer sc = new synContainer();
        new Producer(sc).start();
        new Consumer(sc).start();
    }
}
class Producer extends Thread{
    synContainer container;
    public Producer(synContainer container){
        this.container = container;
    }
    // 生产
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Product(i));
            System.out.println("生产了 "+i+" 个产品。");
        }
    }
}
class Consumer extends Thread{
    synContainer container;
    public Consumer(synContainer container){
        this.container = container;
    }
    // 消费
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了-->"+container.pop().id+" 个产品。");
        }
    }
}
class Product{
    int id;
    public Product(int id){
        this.id = id;
    }
}
class synContainer{
    // 容器大小
    Product[] products=new Product[10];
    // 产品计数器
    int count=0;

    // 生产者放入产品
    public synchronized void push(Product product){
        // 是否要生产
        if(count==products.length){
            // 需要消费者消费，生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        // 要生产
        products[count]=product;
        count++;
        // 通知消费者消费
        this.notifyAll();
    }

    // 消费者购买产品
    public synchronized Product pop(){
        // 能否购买
        if(count==0){
            // 需要生产者生产，消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        // 可以购买
        count--;
        Product res=products[count];
        // 可以通知生产者生产
        this.notifyAll();
        return res;
    }
}
